home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-20 | 23.6 KB | 754 lines | [TEXT/CWIE] |
- ///////////////////////////////////////////////////////////////////////////////
- //
- // include's
- //
-
- #include "ocheaders.h"
- #include "CBaseControl.h"
- #include "CErrorControl.h"
- #include "CGradientControl.h"
- #include "Colors.h"
- #include "FnAssert.h"
- #include "BDAssert.h"
- #include "BDVerify.h"
- #include "BDUtils.h"
- #include "dispatch.h"
- #include "CError.h"
- #include "CGradientError.h"
- #include <ctype.h>
- #include <math.h>
- #include <stdio.h>
- #include <algobase.h>
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::CGradientControl
- //
- // Constructor
- //
-
- CGradientControl::CGradientControl(void) : CBaseControl()
- {
- // protected:
- mMainOffscreenGWorld = nil;
- mPixOffscreenPixMap = nil;
- mRectOffscreenBounds = gZeroRect;
- mDirection = Horizontal;
- mStartColor = RGB_WHITE;
- mEndColor = RGB_BLACK;
- #if defined (start_end_point)
- mStartPoint = gZeroPoint;
- mEndPoint = gZeroPoint;
- #endif
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::~CGradientControl
- //
- // Destructor
- //
-
- CGradientControl::~CGradientControl(void)
- {
- // clean up offscreen world
- if (mMainOffscreenGWorld != nil)
- {
- DisposeGWorld(mMainOffscreenGWorld);
- mMainOffscreenGWorld = nil;
- mPixOffscreenPixMap = nil;
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::IUnknown::QueryInterface
- //
- // Returns a pointer to the specified interface on a component to which a
- // client currently holds an interface pointer.
- //
-
- STDMETHODIMP
- CGradientControl::QueryInterface(REFIID inRefID, void** outObj)
- {
- if (inRefID == IID_IBindStatusCallback)
- return CBaseBindStatusCallback::QueryInterface(inRefID, outObj);
- else
- return CBaseControl::QueryInterface(inRefID, outObj);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::IInProcObject::Draw
- //
- // Context the drawing context for ActiveX - includes the port
- //
- // Draw the Gradient object.
- //
-
- STDMETHODIMP
- CGradientControl::Draw(THIS_ DrawContext* Context)
- {
- if (Context->DrawAspect != DVASPECT_CONTENT)
- return ResultFromScode(DV_E_DVASPECT);
-
- this->PrepareOffscreenWorld(Context); // get the main offscreen world setup and ready
-
- // get the offscreen bitmap
- BitMap* offscreenBitMap = this->GetOffscreenBitMap();
-
- // draw the Gradient
- this->RenderGradientControl(mRectOffscreenBounds);
-
- // Move it
- this->MoveOnScreen(offscreenBitMap, Context);
-
- // unlock, and unload
- this->ReleaseOffscreenBitMap(offscreenBitMap);
-
- return ResultFromScode(S_OK);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::IPersistPropertyBag::Load
- //
- // PropBag container that holds all the properties passed in
- // ErrorLog ptr to an error log
- //
- // Sets the data members that represent the user definable properties from the URL.
- //
-
- STDMETHODIMP
- CGradientControl::Load(IPropertyBag* PropBag, IErrorLog* ErrorLog)
- {
- SCODE theSCode = LoadTextState(PropBag, ErrorLog);
- return ResultFromScode(theSCode);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::IPersistPropertyBag::LoadTextState
- //
- // pPropertyBag container that holds all the properties passed in
- // pErrorLog ptr to an error log
- //
- // Sets the data members that represent the user definable properties from the container stream.
- //
-
- STDMETHODIMP CGradientControl::LoadTextState(IPropertyBag *pPropertyBag,IErrorLog *pErrorLog)
- {
- // const long maxLength = 256;
- char propertyString[maxPropertyStringLength];
-
- // try to load in each property. if we can't get it, then leave
- // things at the default.
-
- // The gradient direction
- if (::LoadPropertyString(pPropertyBag, "direction", propertyString, maxPropertyStringLength, pErrorLog))
- mDirection = (enumDirection)(atoi(propertyString));
-
- // The end gradient color
- if (::LoadPropertyString(pPropertyBag, "endcolor", propertyString, maxPropertyStringLength, pErrorLog))
- this->LoadColor(&mEndColor, propertyString);
-
- // The start gradient color
- if (::LoadPropertyString(pPropertyBag, "startcolor", propertyString, maxPropertyStringLength, pErrorLog))
- this->LoadColor(&mStartColor, propertyString);
-
- #if defined (start_end_point)
- // The end point
- if (::LoadPropertyString(pPropertyBag, "startpoint", propertyString, maxPropertyStringLength, pErrorLog))
- mStartPoint = atoi(propertyString);
-
- // The begin point
- if (::LoadPropertyString(pPropertyBag, "endpoint", propertyString, maxPropertyStringLength, pErrorLog))
- mEndPoint = atoi(propertyString);
- #endif
- return ResultFromScode(S_OK);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::LoadColor
- //
- //
- // theColor an RGBColor that defines the color tuple exactly (i.e., not indexed)
- // colorString a string with a color in it repesented in ASCII
- //
- // Sets the color data member based on the value of the user definable property.
- //
-
- Boolean CGradientControl::LoadColor(RGBColor * theColor, char * colorString)
- {
- Boolean didSet = true;
-
- for (short i = 0; i < strlen(colorString); i++)
- tolower(colorString[i]);
-
- if (streq(colorString, "black"))
- *theColor = RGB_BLACK;
- else if (streq(colorString, "white"))
- *theColor = RGB_WHITE;
- else if (streq(colorString, "red"))
- *theColor = RGB_RED;
- else if (streq(colorString, "green"))
- *theColor = RGB_GREEN;
- else if (streq(colorString, "blue"))
- *theColor = RGB_BLUE;
- else if (streq(colorString, "cyan"))
- *theColor = RGB_CYAN;
- else if (streq(colorString, "magenta"))
- *theColor = RGB_MAGENTA;
- else if (streq(colorString, "yellow"))
- *theColor = RGB_YELLOW;
- else
- {
- didSet = false; // reverse Boolean logic -- false unless we succeed
-
- // We're expecting a 32-bit hex RGB value in the format #00bbggrr.
- //
- // NOTE: To be compatible with Windows, if the high-order bit is set,
- // the low-order byte is supposed to be treated as a system color index.
- // We'll punt on this for now.
-
- Boolean punt = false;
-
- // sanity check on string format. #bbggrr, #0bbggrr, or #00bbggrr.
- int len = strlen(colorString);
- if ((colorString[0] == '#') && (len >= 7) && (len <= 9))
- {
- // if len == 9, the input may be trying to set the high-order
- // bit. Check for this and punt if so.
- if (len == 9)
- {
- char * sHi = "0x??";
- short iHi = 0;
-
- strncat(sHi, colorString, 2);
- sscanf(sHi, "%hx", &iHi);
-
- punt = iHi & 0x40;
- }
-
- if (!punt) // if we're NOT setting hi-order bit...
- {
- const int mostSignificantBits = 8; // amount to shift to move a byte
- const int numComponents = 3; // number of array components - one ea for R,G & B
- const int redPos = 2; // array position for component
- const int greenPos = 1; // array position for component
- const int bluePos = 0; // array position for component
-
- unsigned short desiredColorArray[numComponents]; // a COLORREF, as an array
-
- for (short i = 0, pos = len-2; i < numComponents; i++, pos -= 2)
- {
- char * sColor = "0x??";
- short aShort = 0;
- strncpy(&sColor[2], &colorString[pos], 2);
- sscanf(sColor, "%hx", &aShort);
- ASSERT((aShort <= 0xff), "Range check error!");
- desiredColorArray[i] = aShort << mostSignificantBits;// move the color component value into the ms bits
- }
-
- // return the color that we went to all that trouble to set
- theColor->red = (unsigned short) desiredColorArray[redPos];
- theColor->green = (unsigned short) desiredColorArray[greenPos];
- theColor->blue = (unsigned short) desiredColorArray[bluePos];
-
- // success, so tell the world
- didSet = true;
- }
- }
- }
-
- return didSet;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::PrepareOffscreenWorld
- //
- // Context the drawing context for ActiveX - includes the port
- //
- // Creates the offscreen gworld that is the current display.
- //
-
- void CGradientControl::PrepareOffscreenWorld(const DrawContext* Context) // MMF
- {
- try
- {
- // get the current drawing environment
-
- // If there's already an offscreen GWorld, get rid of it.
- if (mMainOffscreenGWorld != nil)
- {
- ::DisposeGWorld(mMainOffscreenGWorld);
- mMainOffscreenGWorld = nil;
- }
-
- // Define the size of the GWorld's bounding boxes -- same size as onscreen
- short rightBounds = Context->Location.right - Context->Location.left;
- short bottomBounds = Context->Location.bottom - Context->Location.top;
- ::SetRect(&mRectOffscreenBounds, 0, 0, rightBounds, bottomBounds);
-
- // Allocate a new GWorld for the offscreen drawing and store its PixMap.
- GDHandle currDevice = ::GetGDevice();
- short targetDepth = (**(**currDevice).gdPMap).pixelSize; // how many pixels deep are we?
- QDErr err = ::NewGWorld(&mMainOffscreenGWorld, thousandsOfColorsDepth, &mRectOffscreenBounds, 0, nil, 0);
-
- if (!err)
- {
- mPixOffscreenPixMap = ::GetGWorldPixMap(mMainOffscreenGWorld);
-
- // we should now have a gworld
- if (mMainOffscreenGWorld == nil || mPixOffscreenPixMap == nil)
- throw CGradientError(CONTROL_GWORLD_ALLOCATION_ERROR, this);
- }
- }
-
- // error handling
- catch (CGradientError &GradientError)
- {
- GradientError.HandleError();
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::MoveOnScreen
- //
- // offscreenBitMap a PixMap or BitMap pointer
- // Context the drawing context for ActiveX - includes the port
- //
- // Computes the size of the rect needed to hold the rotated rect.
- //
-
- void CGradientControl::MoveOnScreen(const BitMap * offscreenBitMap, const DrawContext* Context) // MMF
- {
- // Set the colors
- ::RGBForeColor(&RGB_BLACK);
- ::RGBBackColor(&RGB_WHITE);
-
- // actually move the bits
- ::CopyBits( offscreenBitMap, &(Context->Port->portBits),
- &mRectOffscreenBounds, &Context->Location,
- srcCopy + ditherCopy, nil);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::GetOffscreenBitMap
- //
- // returns BitMap a PixMap or BitMap pointer
- //
- // Returns a BitMap/PixMap that is part of the offscreen world - ready to draw into.
- //
-
- BitMap * CGradientControl::GetOffscreenBitMap(void)
- {
- // sanity check
- assert((mPixOffscreenPixMap != nil));
-
- // Lock n load the pixMap handle 'till we're done with it
- ::LockPixels(mPixOffscreenPixMap);
-
- // lock handle so it does not float on us
- ::HLock((Handle)mPixOffscreenPixMap);
-
- // Note the bitmap, now that we've locked n loaded
- BitMap* offscreenBitMap = (BitMap *)(*mPixOffscreenPixMap);
- assert((offscreenBitMap != nil));
-
- return offscreenBitMap;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::ReleaseOffscreenBitMap
- //
- // offscreenBitMap an offscreenBitMap that we are through with and would like to purge.
- //
- // Unlocks handles and pixels in preparation for disposing of a GWorld
- //
-
- void CGradientControl::ReleaseOffscreenBitMap(BitMap * offscreenBitMap)
- {
-
- // we are done with this handle so let it float
- ::HUnlock((Handle)mPixOffscreenPixMap);
-
- // Release the pixMap handle
- ::UnlockPixels(mPixOffscreenPixMap);
-
- // Set this to nil just as a safety factor
- offscreenBitMap = nil;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CGradientControl::RenderGradientControl
- //
- // No params no parameters are passed or returned
- //
- // Actually does the drawing of the Gradient. It creates the content GWorld. Then
- // rotates it as needed. Then blits it into the offscreen PixMap (data member).
- //
-
- void CGradientControl::RenderGradientControl(const Rect contentRect)
- {
- QDErr theErr;
- try
- {
- GWorldPtr contentGWorld = nil; // init cause were anal
-
- GDHandle currDevice = ::GetGDevice();
- short targetDepth = (**(**currDevice).gdPMap).pixelSize; // how many pixels deep are we?
-
- // alloc the output GWorld and save results of failure
-
- // create content PixMap:
- theErr = ::NewGWorld(&contentGWorld, targetDepth, &contentRect, 0, nil, 0);
- assert(theErr == noErr);
- if(theErr != noErr)
- throw CGradientError(GWORLD_ALLOCATION_ERROR, this);
-
- // Store the current port and device before switching to the offscreen world.
- CGrafPtr currentPort;
- GDHandle currentDevice;
- ::GetGWorld(¤tPort, ¤tDevice);
-
- // Switch to the content GWorld and lock the offscreen buffer in memory.
- ::SetGWorld(contentGWorld, nil);
- PixMapHandle contentPixMap = ::GetGWorldPixMap(contentGWorld);
- ::LockPixels(contentPixMap);
-
- ::RGBBackColor(&mEndColor);
- // pre erase the content so that it is ready to go:
- ::EraseRect(&contentRect);
-
- unsigned short maxRed = maxRGBComponentValue;
- unsigned short maxGreen = maxRGBComponentValue;
- unsigned short maxBlue = maxRGBComponentValue;
-
- short width = contentRect.right - contentRect.left; // compute the width of the rect
- short height = contentRect.bottom - contentRect.top; // compute the height of the rect
-
- RGBColor theColor = {0, 0, 0}; // the current color in the gray ramp
- Rect sliceRect = gZeroRect; // init to zero cause were anal
- unsigned short colorSlice = 0; // mo ditto
- unsigned short sliceNum = 0; // ditto
-
- switch(mDirection)
- {
- case Horizontal:
- {
- // Draw now that things are ready to go:
- colorSlice = (unsigned short)(maxRGBComponentValue/width);// the amount to incr by for each slice of the gradient
- const short sliceWidth = 1;
-
- for(sliceNum = 0; sliceNum < width; sliceNum++)
- {
- theColor.red = sliceNum * colorSlice;
- theColor.green = sliceNum * colorSlice;
- theColor.blue = sliceNum * colorSlice;
-
- ::RGBForeColor(&theColor);
-
- ::SetRect(&sliceRect, (short)sliceNum, 0, sliceNum + sliceWidth, height);
- assert(ValidRect(sliceRect));
-
- ::PaintRect(&sliceRect); // paint the gray transform filter
- }
- // restore orig gworld
- ::SetGWorld(currentPort, nil);
-
- ::RGBForeColor(&mStartColor);
- ::RGBBackColor(&mEndColor);
-
- ::CopyBits((BitMap *)(*contentPixMap), (BitMap *)(*mPixOffscreenPixMap),
- &(**contentPixMap).bounds, &contentRect, srcCopy + ditherCopy, nil);
- break;
- }// case Horizontal
-
- case Vertical:
- {
- // Draw now that things are ready to go:
- colorSlice = (unsigned short)(maxRGBComponentValue/height);// the amount to incr by for each slice of the gradient
- const short sliceHeight = 1;
-
- for(sliceNum = 0; sliceNum < height; sliceNum++)
- {
- theColor.red = sliceNum * colorSlice;
- theColor.green = sliceNum * colorSlice;
- theColor.blue = sliceNum * colorSlice;
- ::RGBForeColor(&theColor);
-
- ::SetRect(&sliceRect, 0, sliceNum, width, sliceNum + sliceHeight);
- assert(ValidRect(sliceRect));
-
- ::PaintRect(&sliceRect); // paint the gray transform filter
- }
- // restore orig gworld
- ::SetGWorld(currentPort, nil);
-
- ::RGBForeColor(&mStartColor);
- ::RGBBackColor(&mEndColor);
-
- ::CopyBits((BitMap *)(*contentPixMap), (BitMap *)(*mPixOffscreenPixMap),
- &(**contentPixMap).bounds, &contentRect, srcCopy + ditherCopy, nil);
- break;
- }// case Vertical
-
- case BothHV: // towards center
- {
- // Draw now that things are ready to go:
- unsigned short maxDimension = (unsigned short)(max(height,width))/2;
- colorSlice = maxRGBComponentValue/maxDimension;// the amount to incr by for each slice of the gradient
-
- ::SetRect(&sliceRect, 0, 0, width, height);
- assert(ValidRect(sliceRect));
-
- for(sliceNum = 0; sliceNum < maxDimension; sliceNum++)
- {
- theColor.red = sliceNum * colorSlice;
- theColor.green = sliceNum * colorSlice;
- theColor.blue = sliceNum * colorSlice;
- ::RGBForeColor(&theColor);
-
- ::PaintRect(&sliceRect); // paint the gray transform filter
-
- // get ready for the next pass:
- // shrink the rect till it goes to zero in both dimensions (but not less than zero)
- ::InsetRect(&sliceRect, sliceNum < width/2 ? 1 : 0, sliceNum < height/2 ? 1 : 0);
- assert(ValidRect(sliceRect));
- }
- // restore orig gworld
- ::SetGWorld(currentPort, nil);
-
- ::RGBForeColor(&mStartColor);
- ::RGBBackColor(&mEndColor);
-
- ::CopyBits((BitMap *)(*contentPixMap), (BitMap *)(*mPixOffscreenPixMap),
- &(**contentPixMap).bounds, &contentRect, srcCopy + ditherCopy, nil);
- break;
- }// case BothHV
-
- case Corner: // towards corner gradient
- {
- // Draw now that things are ready to go:
- short radius = (short)(sqrt(height*height + width*width) + 1);
- ::SetRect(&sliceRect, -radius, -radius, radius, radius);
-
- colorSlice = maxRGBComponentValue/radius;// the amount to incr by for each slice of the gradient
-
- for(sliceNum = 0; sliceNum < radius; sliceNum++)
- {
- theColor.red = sliceNum * colorSlice;
- theColor.green = sliceNum * colorSlice;
- theColor.blue = sliceNum * colorSlice;
- ::RGBForeColor(&theColor);
-
- ::PaintOval(&sliceRect); // paint the gray transform filter
-
- // get ready for the next pass:
- // shrink the rect till it goes to zero in both dimensions (but not less than zero)
- ::InsetRect(&sliceRect, 1, 1);
- assert(ValidRect(sliceRect));
- }
- // restore orig gworld
- ::SetGWorld(currentPort, nil);
-
- ::RGBForeColor(&mStartColor);
- ::RGBBackColor(&mEndColor);
-
- ::CopyBits((BitMap *)(*contentPixMap), (BitMap *)(*mPixOffscreenPixMap),
- &(**contentPixMap).bounds, &contentRect, srcCopy + ditherCopy, nil);
- break;
- }// case Corner
-
- case DiagDn:
- {
- // create temp PixMap:
- short tempWidth = width * 2; // make the width twice that of the content rect…
- short tempHeight = height; // …the height stays the same
- GWorldPtr tempGWorld = nil; // init cause were anal
- Rect tempRect = {0, 0, tempHeight, tempWidth};
- theErr = ::NewGWorld(&tempGWorld, targetDepth , &tempRect, 0, nil, 0);
- assert(theErr == noErr);
- if(theErr != noErr)
- throw CGradientError(GWORLD_ALLOCATION_ERROR, this);
-
- // Switch to the content GWorld and lock the offscreen buffer in memory.
- ::SetGWorld(tempGWorld, nil);
- PixMapHandle tempPixMap = ::GetGWorldPixMap(tempGWorld);
- ::LockPixels(tempPixMap);
- HLock((Handle)tempPixMap);
-
- ::RGBBackColor(&mEndColor);
- // pre erase the content so that it is ready to go:
- ::EraseRect(&tempRect);
-
- // Draw now that things are ready to go:
- colorSlice = (unsigned short)(maxRGBComponentValue/width);// the amount to incr by for each slice of the gradient
- const short sliceWidth = 1;
-
- for(sliceNum = 0; sliceNum <= width; sliceNum++) // overpaint by one so that we overlap the two merging rects
- {
- theColor.red = sliceNum * colorSlice;
- theColor.green = sliceNum * colorSlice;
- theColor.blue = sliceNum * colorSlice;
- ::RGBForeColor(&theColor);
-
- // do one stripe on the left…
- ::SetRect(&sliceRect, sliceNum, 0, sliceNum + sliceWidth, height);
- assert(ValidRect(sliceRect));
- ::PaintRect(&sliceRect); // paint the gray transform filter
-
- // …and one stripe on the right side of tempRect
- ::SetRect(&sliceRect, tempWidth - sliceNum, 0, tempWidth + sliceWidth - sliceNum, height);
- assert(ValidRect(sliceRect));
- ::PaintRect(&sliceRect); // paint the gray transform filter
- }// for
-
- // skew rect by copying with offset growing while copying into content:
- // restore content gworld
- ::SetGWorld(currentPort, currentDevice);
-
- ::RGBForeColor(&mStartColor);
- ::RGBBackColor(&mEndColor);
-
- Rect sliceOfTempRect = gZeroRect;
- Rect sliceOfContentRect = gZeroRect;
- double slopeRecip = (double)width / (double)height;
- short xOffset = 0; // init to nada
- double sliceNumOffset = 0.0;// ditto
-
- for(sliceNum = 0; sliceNum < height; sliceNum++, sliceNumOffset++)
- {
- // build the src rect:
- xOffset = (short)(sliceNumOffset * slopeRecip);
- ::SetRect(&sliceOfTempRect, width - xOffset, sliceNum, tempWidth - xOffset, sliceNum + sliceWidth);
- assert(ValidRect(sliceOfTempRect));
-
- // build the target rect:
- ::SetRect(&sliceOfContentRect, 0, sliceNum, width, sliceNum + sliceWidth);
- assert(ValidRect(sliceOfContentRect));
-
- // copy the map one slice at a time while moving across the filter
- ::CopyBits((BitMap *)(*tempPixMap), (BitMap *)(*mPixOffscreenPixMap),
- &sliceOfTempRect, &sliceOfContentRect, srcCopy + ditherCopy, nil);
- }// for
-
- ::UnlockPixels(tempPixMap);
- ::HUnlock((Handle)tempPixMap);
- ::DisposeGWorld(tempGWorld);
-
- break;
- }// case DiagDn
-
- case DiagUp:
- {
- // create temp PixMap:
- short tempWidth = width * 2; // make the width twice that of the content rect…
- short tempHeight = height; // …the height stays the same
- GWorldPtr tempGWorld = nil; // init cause were anal
- Rect tempRect = {0, 0, tempHeight, tempWidth};
- theErr = ::NewGWorld(&tempGWorld, targetDepth , &tempRect, 0, nil, 0);
- assert(theErr == noErr);
- if(theErr != noErr)
- throw CGradientError(GWORLD_ALLOCATION_ERROR, this);
-
- // Switch to the content GWorld and lock the offscreen buffer in memory.
- ::SetGWorld(tempGWorld, nil);
- PixMapHandle tempPixMap = ::GetGWorldPixMap(tempGWorld);
- ::LockPixels(tempPixMap);
- ::HLock((Handle)tempPixMap);
-
- ::RGBBackColor(&mEndColor);
- // pre erase the content so that it is ready to go:
- ::EraseRect(&tempRect);
-
-
- // Draw now that things are ready to go:
- colorSlice = (unsigned short)(maxRGBComponentValue/width);// the amount to incr by for each slice of the gradient
- const short sliceWidth = 1;
-
- for(sliceNum = 0; sliceNum <= width; sliceNum++) // overpaint by one so that we overlap the two merging rects
- {
- theColor.red = sliceNum * colorSlice;
- theColor.green = sliceNum * colorSlice;
- theColor.blue = sliceNum * colorSlice;
- ::RGBForeColor(&theColor);
-
- // do one stripe on the left…
- ::SetRect(&sliceRect, sliceNum, 0, sliceNum + sliceWidth, height);
- assert(ValidRect(sliceRect));
- ::PaintRect(&sliceRect); // paint the gray transform filter
-
- // …and one stripe on the right side of tempRect
- ::SetRect(&sliceRect, tempWidth - sliceNum, 0, tempWidth + sliceWidth - sliceNum, height);
- assert(ValidRect(sliceRect));
- ::PaintRect(&sliceRect); // paint the gray transform filter
- }// for
-
- // skew rect by copying with offset growing while copying into content:
- // restore content gworld
- ::SetGWorld(currentPort, currentDevice);
-
- ::RGBForeColor(&mStartColor);
- ::RGBBackColor(&mEndColor);
-
- Rect sliceOfTempRect = gZeroRect;
- Rect sliceOfContentRect = gZeroRect;
- double slopeRecip = (double)width / (double)height;
- short xOffset = 0; // init to nada
- double sliceNumOffset = 0.0;// ditto
-
- for(sliceNum = 0; sliceNum < height; sliceNum++, sliceNumOffset++)
- {
- // build the src rect:
- xOffset = (short)(sliceNumOffset * slopeRecip);
- ::SetRect(&sliceOfTempRect, xOffset, sliceNum, width + xOffset, sliceNum + sliceWidth);
- assert(ValidRect(sliceOfTempRect));
-
- // build the target rect:
- ::SetRect(&sliceOfContentRect, 0, sliceNum, width, sliceNum + sliceWidth);
- assert(ValidRect(sliceOfContentRect));
-
- // copy the map one slice at a time while moving across the filter
- ::CopyBits((BitMap *)(*tempPixMap), (BitMap *)(*mPixOffscreenPixMap),
- &sliceOfTempRect, &sliceOfContentRect, srcCopy + ditherCopy, nil);
- }// for
-
- ::UnlockPixels(tempPixMap);
- ::HUnlock((Handle)tempPixMap);
- ::DisposeGWorld(tempGWorld);
-
- break;
- }// case DiagUp
-
- case PointBased:
- case LineBased:
- ASSERT(0, "Not yet implemented!");
-
- default:
- break;
- }// switch
-
- ::DisposeGWorld(contentGWorld);
-
- }// try
-
- // error handling
- catch(CGradientError &gradientError)
- {
- gradientError.HandleError();
- }
-
- }
-
-
- // end-of-file ////////////////////////////////////////////////////////////////
-
-